package yxy.game.pm2.active.module;

import org.joda.time.DateTime;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.*;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.active.ActiveUtil;
import yxy.game.pm2.active.module.actcontrol.activeControl;
import yxy.game.pm2.active.module.actfavoritewarlord.FavouritePackage;
import yxy.game.pm2.active.module.subordinateclass.Act_许愿瓶大奖纪录;
import yxy.game.pm2.active.module.subordinateclass.flop.FlopCard;
import yxy.game.pm2.bean.*;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.message.BottleWishMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.hitplanegame.HitPlaneGameModule;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.*;
import java.util.stream.Collectors;

public class ActiveModule_国庆寻宝 extends PlayerModule {

    //bean ----------------------------------------------------

    public static final int acttype = Constant.TREASURE_HUNT;

    private int day;       //当前天数

    private DateTime update;    //刷新时间

    private int totalChargeMoney; //总充钱数量

    private ArrayList<Integer> hasRewardDays = new ArrayList<Integer>();//已经领取的天数

    private ArrayList<FavouritePackage> dgifts = new ArrayList<FavouritePackage>();//商品信息

    private ArrayList<FavouritePackage> accumulateDgifts = new ArrayList<FavouritePackage>();//累充信息

    private ArrayList<Integer> hasRewardId = new ArrayList<>();//领取过的累充礼包

    private int floor;//当前层数,默认0层,前端发送下一层后加一

    private HashMap<Integer, FlopCard> fcmap = new HashMap<>();//30个牌子信息

    private ArrayList<Integer> floorAward = new ArrayList<>();//领取过的层奖励

    public ArrayList<Integer> getFloorAward() {
        return floorAward;
    }

    public void setFloorAward(ArrayList<Integer> floorAward) {
        this.floorAward = floorAward;
    }

    public int getFloor() {
        return floor;
    }

    public void setFloor(int floor) {
        this.floor = floor;
    }

    public HashMap<Integer, FlopCard> getFcmap() {
        return fcmap;
    }

    public void setFcmap(HashMap<Integer, FlopCard> fcmap) {
        this.fcmap = fcmap;
    }

    public ArrayList<Integer> getHasRewardId() {
        return hasRewardId;
    }

    public void setHasRewardId(ArrayList<Integer> hasRewardId) {
        this.hasRewardId = hasRewardId;
    }

    public int getTotalChargeMoney() {
        return totalChargeMoney;
    }

    public void setTotalChargeMoney(int totalChargeMoney) {
        this.totalChargeMoney = totalChargeMoney;
    }

    public ArrayList<FavouritePackage> getAccumulateDgifts() {
        return accumulateDgifts;
    }

    public void setAccumulateDgifts(ArrayList<FavouritePackage> accumulateDgifts) {
        this.accumulateDgifts = accumulateDgifts;
    }

    public ArrayList<FavouritePackage> getDgifts() {
        return dgifts;
    }

    public void setDgifts(ArrayList<FavouritePackage> dgifts) {
        this.dgifts = dgifts;
    }


    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public DateTime getUpdate() {
        return update;
    }

    public void setUpdate(DateTime update) {
        this.update = update;
    }

    public ArrayList<Integer> getHasRewardDays() {
        return hasRewardDays;
    }

    public void setHasRewardDays(ArrayList<Integer> hasRewardDays) {
        this.hasRewardDays = hasRewardDays;
    }
    //func ----------------------------------------------------

    //寻宝活动充值累计
    public void addChargeMoney(int price) {
        int totalChargeMoney = getTotalChargeMoney();
        setTotalChargeMoney(totalChargeMoney + price / 100);
        set();
    }


    /**
     * 创建ActiveModule_寻宝
     *
     * @param playerCode
     */
    public static ActiveModule_国庆寻宝 create(String playerCode) {
        AreaBean ab = AreaModule.area(playerCode);
        activeControl sai = activeControl.get(ab.getAreaId(), acttype);
        if (sai != null) {
            ActiveModule_国庆寻宝 am = new ActiveModule_国庆寻宝();
            am.setPlayerCode(playerCode);
            am.setTimeline(sai.getTimeline());
            am.reset(ab.getAreaId());
            am.set();
            return am;
        }
        return null;
    }

    public void update() {
        PlayerBean pb = PlayerBean.get(getPlayerCode());
        ServerBean sb = ServerBean.get(pb.getServerId());
        activeControl sai = activeControl.get(String.valueOf(sb.getAreaId()), String.valueOf(acttype));
        if (sai == null) {
            return;
        }

        // 区活动关闭，但自己活动没关闭，更新活动时间
        if (!sai.running()) {
            setTimeline(sai.getTimeline());
            //回收
            try {
                //todo 活动关闭，清除背包的没消耗完的活动道具
                acttreasuredata data = DataCenter.getData(1, acttreasuredata.class);
                int costid = data.getCostid();//消耗的道具id
                //如果背包存在就转成对应物品邮件发送
                Currency currency = Item.get(getPlayerCode(), CurrencyType.CT_物品, costid);
                if (currency.getNumber() > 0) {
                    item item_ = DataCenter.getData(costid, item.class);
                    new CurrencyHandle().cost(getPlayerCode(), CCReason.国庆寻宝活动道具清空, currency);
                    //邮件补偿
                    List<Currency> list = new ArrayList<>();
                    Currency reward = yxy.game.pm2.bean.Currency.create(item_.getReclaimtype(), item_.getReclaimid(), currency.getNumber() * item_.getReclaimnum());
                    list.add(reward);
                    String title = GameString.活动结束自动回收_title().getText();
                    String content = GameString.活动结束自动回收_msg("国庆寻宝", "" + currency.getNumber(), "" + item_.getName(), "" + currency.getNumber() * item_.getReclaimnum()).getText();
                    new MailHandle().sendMail(getPlayerCode(), MailTypeEnum.Mail, title, content, CCReason.国庆寻宝活动道具清空, list);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            set();
        }

        if (!sai.running() && running()) {
            setTimeline(sai.getTimeline());
            set();
            return;
        }

        // 区活动开启，但自己没开启
        if (sai.running() && !running()) {
            setTimeline(sai.getTimeline());
            reset(sb.getAreaId());
            set();
        }

        //更新天数(转天更新)
        DateTime now = DateTime.now();
        int days = ActiveUtil.days(getUpdate(), now);
        if (days >= 1) {
            DateTime startTime = sai.getTimeline().getStartTime();
            int activityHasPassTime = ActiveUtil.days(startTime, now) + 1;
            setDay(activityHasPassTime);
            setUpdate(now);
            set();
        }
    }

    //重置
    private void reset(int areaId) {
        //获取翻牌表格数据
        Map<String, acttreasurefloprandom> afrmap = DataCenter.getAllData(acttreasurefloprandom.class);
        ArrayList<Integer> afrids = new ArrayList(afrmap.keySet());
        Collections.shuffle(afrids);
        for (int i = 0; i < afrids.size(); i++) {
            acttreasurefloprandom afr = afrmap.get(String.valueOf(afrids.get(i)));
            FlopCard fc = new FlopCard();
            fc.setPosition(i + 1);
            fc.setId(afr.getId());
            fc.setFlop(false);
            fc.setGrand(afr.getType() == 2);//type-2 是下一层的意思,和翻牌活动有些不同
            getFcmap().put(i + 1, fc);
        }
        //重置当前层数-0层
        setFloor(Constant.ZERO);
        //当前活动天数重置
        setDay(1);
        setUpdate(DateTime.now());
        setHasRewardDays(new ArrayList<Integer>());

        //商品重置
        Map<String, acttreasureshop> shopMap = DataCenter.getAllData(acttreasureshop.class);        //商品表

        setDgifts(new ArrayList<>());
        for (acttreasureshop data : shopMap.values()) {
            FavouritePackage dgift = new FavouritePackage();
            dgift.setId(data.getId());
            dgift.setGoodsid(data.getPurchasever());
            dgift.setNumlimit(data.getNumber());//限购次数
            dgift.setType(data.getLimittype());//类型
            dgift.setBuyNum(0); //已购买次数；
            getDgifts().add(dgift);
        }
        //总充值金额
        setTotalChargeMoney(0);
        //累充奖励
        setAccumulateDgifts(new ArrayList<>());
        Map<String, acttreasurechargereward> accumulateMap = DataCenter.getAllData(acttreasurechargereward.class);
        for (acttreasurechargereward data : accumulateMap.values()) {
            FavouritePackage dgift = new FavouritePackage();
            dgift.setId(data.getId());
            getAccumulateDgifts().add(dgift);
        }

        setHasRewardId(new ArrayList<>());

        //重置领取过得层奖励
        setFloorAward(new ArrayList<>());

        //重置飞机玩法
        HitPlaneGameModule module = HitPlaneGameModule.get(getPlayerCode());
        module.reset(getPlayerCode());
    }

    public Collection<BottleWishMessage.BottleWishAwardsInfo> getLog(int areaId) {
        List<BottleWishMessage.BottleWishAwardsInfo> list = new ArrayList<>();
        try {
            List<Act_许愿瓶大奖纪录> msgs = Act_许愿瓶大奖纪录.all(areaId);
            for (Act_许愿瓶大奖纪录 msg : msgs) {
                BottleWishMessage.BottleWishAwardsInfo.Builder ai = BottleWishMessage.BottleWishAwardsInfo.newBuilder();
                ai.setSequence(msg.getTime());
                ai.setItem(new CurrencyHandle().packItem(msg.getCur()));
                ai.setName(msg.getName());
                list.add(ai.build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return list;
    }


    /**
     * 解锁单 加 设置购买时间
     *
     * @param goodsid
     */
    public void unlockGiftPackageAndSetBuyTime(int goodsid) {
        for (FavouritePackage dgift : getDgifts()) {
            if (dgift.getGoodsid() == goodsid) {
                int buyNum = dgift.getBuyNum();
                buyNum++;
                dgift.setBuyNum(buyNum); //修改已购买数量
                set();
            }
        }
    }

    /**
     * 重置格子
     */
    public void resetCell() {
        getFcmap().clear();
        Map<String, acttreasurefloprandom> afrmap = DataCenter.getAllData(acttreasurefloprandom.class);
        ArrayList<Integer> afrids = new ArrayList(afrmap.keySet());
        Collections.shuffle(afrids);
        for (int i = 0; i < afrids.size(); i++) {
            acttreasurefloprandom afr = afrmap.get(String.valueOf(afrids.get(i)));
            FlopCard fc = new FlopCard();
            fc.setPosition(i + 1);
            fc.setId(afr.getId());
            fc.setFlop(false);
            fc.setGrand(afr.getType() == 2);//type-2 是下一层的意思,和翻牌活动有些不同
            getFcmap().put(i + 1, fc);
        }
    }


    // redis ---------------------------------------------------------

    static private String key(String playerCode) {
        return String.format("PLAYER:%s:ACTIVE:%S", playerCode, acttype);
    }

    public void set() {
        try {
            setv(key(getPlayerCode()), this);
            check();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 ActiveModule_寻宝
     *
     * @param playerCode
     * @return
     */
    public static ActiveModule_国庆寻宝 get(String playerCode, Boolean isNewPlayer) {
        try {
            ActiveModule_国庆寻宝 module = getv(key(playerCode));
            if (module == null) {

                //新用户不需要去查数据库
                if (!isNewPlayer) {
                    module = MySQLCacheDAO.getV(key(playerCode), ActiveModule_国庆寻宝.class);
                    if (module != null) {
                        module.set();
                    }//同步到redis
                }

                if (module == null) {
                    module = create(playerCode);
                }
            }

            module.update();
            module.check();
            return module;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查看是否有可领取奖励 控制红点
     */
    public void check() {
        if (running()) {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.开启);
        } else {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.关闭);
        }

        if (running()) {
            //签到能领取红点提示
            signInTipe();
            //层数达标领奖红点提示
            bottleWishTipe();
        } else {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.关闭);
        }

    }

    /**
     * 达到层数要求领取奖励红点提示
     */
    private void bottleWishTipe() {
        try {
            Map<String, acttreasurestepreward> allData = DataCenter.getAllData(acttreasurestepreward.class);
            List<Integer> collect = allData.values().stream().filter(_reward -> _reward.getStep() <= floor).map(acttreasurestepreward::getId).collect(Collectors.toList());
            ArrayList<Integer> floorAward = getFloorAward();
            collect.removeAll(floorAward);
            if(collect.size()>=1){
                new TipHandle().updateTip(getPlayerCode(), TipType.活动_国庆寻宝领取红点, true);
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        new TipHandle().updateTip(getPlayerCode(), TipType.活动_国庆寻宝领取红点, false);
    }

    /**
     * 签到能领取红点提示
     */
    private void signInTipe() {
        ArrayList<Integer> hasRewardDays = getHasRewardDays();

        if (hasRewardDays.size() < getDay() && hasRewardDays.size() < 7) {
            new TipHandle().updateTip(getPlayerCode(), TipType.活动_国庆寻宝签到红点, true);
            return;
        }

        new TipHandle().updateTip(getPlayerCode(), TipType.活动_国庆寻宝签到红点, false);
    }


    //存储到数据库的方法
    public static void saveToDB(String playerCode) {
        try {
            String key = key(playerCode);
            if (touchBucket(key).isExists()) {
                ActiveModule_国庆寻宝 activeModule_国庆寻宝 = getv(key(playerCode));
                MySQLCacheDAO.setV(key, activeModule_国庆寻宝);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode) {
        try {
            touchBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }
    // lock==========================================================================

    @Override
    public String lockKey() {
        return String.format("lock:%s", key(getPlayerCode()));
    }


}
